<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" type="text/css" href="./styles_main.css" />
<title>Writing snippets</title>
</head><body>

<ul class="primary-links">
  <li><a href="./index.html">Intro and tutorial</a></li>
  <li><a href="./snippet-organization.html">Howto: organize</a></li>
  <li><a href="./snippet-expansion.html">Howto: expand</a></li>
  <li><a href="./snippet-development.html">Howto: write</a></li>
  <li><a href="./snippet-menu.html">Howto: menu</a></li>
  <li><a href="./faq.html">FAQ</a></li>
  <li><a href="http://yasnippet.googlecode.com/svn/trunk/doc/changelog.html">ChangeLog</a></li>
  <li><a href="http://code.google.com/p/yasnippet/downloads/list">Download</a></li>
</ul>

<p class="original">原文： <a href="http://yasnippet.googlecode.com/svn/trunk/doc/snippet-development.html">http://yasnippet.googlecode.com/svn/trunk/doc/snippet-development.html</a>
<span class="translated-date">(translated on 2010/Dec/21)</span>
<a class="link-to-editors-room" href="http://code.google.com/p/yasnippet-doc-jp/">⇒ 翻訳プロジェクト</a>
</p>

<h1>Writing snippets</h1>

<p class="notice"><strong>〔重要〕</strong> このドキュメントは YASnippet の <strong>SVN trunk</strong> に対して適用されるものです。
SVN trunk は<a href="http://code.google.com/p/yasnippet/source/checkout">こちら</a>から取得できます。
他のバージョンに対するドキュメントは<a href="から取得できます。">こちら</a>で見られます。
</p>

<ul class="toc">
  <li>
    <a href="#snippet-development">Snippet development</a>
    <ul>
      <li><a href="#quickly-finding-snippets">Quickly finding snippets</a></li>
      <li><a href="#using-the-snippet-mode-major-mode">Using the <code>snippet-mode</code> major mode</a></li>
    </ul>
  </li>
  <li>
    <a href="#file-content">File content</a>
    <ul>
      <li><a href="#key-snippet-abbrev"><code># key:</code> snippet abbrev</a></li>
      <li><a href="#name-snippet-name"><code># name:</code> snippet name</a></li>
      <li><a href="#condition-snippet-condition"><code># condition:</code> snippet condition</a></li>
      <li><a href="#group-snippet-menu-grouping"><code># group:</code> snippet menu grouping</a></li>
      <li><a href="#expand-env-expand-environment"><code># expand-env:</code> expand environment</a></li>
      <li><a href="#binding-direct-keybinding"><code># binding:</code> direct keybinding</a></li>
      <li><a href="#contributor-snippet-author"><code># contributor:</code> snippet author</a></li>
    </ul>
  </li>
  <li>
    <a href="#template-syntax">Template syntax</a>
    <ul>
      <li><a href="#plain-text">Plain Text</a></li>
      <li><a href="#embedded-emacs-lisp-code">Embedded Emacs-lisp code</a></li>
      <li><a href="#tab-stop-fields">Tab stop fields</a></li>
      <li><a href="#placeholder-fields">Placeholder fields</a></li>
      <li><a href="#id2">Mirrors</a></li>
      <li><a href="#mirrors-with-transformations">Mirrors with transformations</a></li>
      <li><a href="#fields-with-transformations">Fields with transformations</a></li>
      <li><a href="#choosing-fields-value-from-a-list-and-other-tricks">Choosing fields value from a list and other tricks</a></li>
      <li><a href="#nested-placeholder-fields">Nested placeholder fields</a></li>
    </ul>
  </li>
  <li>
    <a href="#customizable-variables">Customizable variables</a>
    <ul>
      <li><a href="#yas-trigger-key"><code>yas/trigger-key</code></a></li>
      <li><a href="#yas-next-field-key"><code>yas/next-field-key</code></a></li>
      <li><a href="#yas-prev-field-key"><code>yas/prev-field-key</code></a></li>
      <li><a href="#yas-skip-and-clear-key"><code>yas/skip-and-clear-key</code></a></li>
      <li><a href="#yas-good-grace"><code>yas/good-grace</code></a></li>
      <li><a href="#yas-indent-line"><code>yas/indent-line</code></a></li>
      <li><a href="#yas-wrap-around-region"><code>yas/wrap-around-region</code></a></li>
      <li><a href="#yas-triggers-in-field"><code>yas/triggers-in-field</code></a></li>
      <li><a href="#yas-snippet-revival"><code>yas/snippet-revival</code></a></li>
      <li><a href="#yas-after-exit-snippet-hook-and-yas-before-expand-snippet-hook"><code>yas/after-exit-snippet-hook</code> and <code>yas/before-expand-snippet-hook</code></a></li>
    </ul>
  </li>
  <li><a href="#importing-textmate-snippets">Importing TextMate snippets</a></li>
</ul>

<div class="contents">

<h2 id="snippet-development">スニペットの開発</h2>

<h3 id="quickly-finding-snippets">スニペットをすばやく見つける</h3>

<p>スニペットファイルをすばやく見つける方法はいくつかあります：
</p>

<dl>
  <dt>・<code>M-x yas/new-snippet</code></dt>
  <dd>
    <p>スニペット名の入力プロンプトを開き、それからそのスニペットを置くのに適したディレクトリを推測し、そのディレクトリが存在しない場合は作成するか否かのプロンプトを表示します。
    最後に、あなたがスニペットを書けるように、<code>snippet-mode</code> に設定された新しいバッファを開きます。
    </p>
  </dd>

  <dt>・<code>M-x yas/find-snippets</code></dt>
  <dd>
    <p><code>find-file-other-window</code> と同様に、読み込み済みのスニペットが置いてあったディレクトリで（もしそれが存在したならば）、スニペットファイルを開きます。
    ここで使われるディレクトリ検索ロジックは <code>M-x yas/new-snippet</code> に似ています。
    </p>
  </dd>

  <dt>・<code>M-x yas/visit-snippet-file</code></dt>
  <dd>
    <p><code>yas/insert-snippet</code> と同様に、展開したいスニペットの名前を入力するプロンプトを表示します。
    ただし、実際にそれを展開する代わりに、そのスニペットの定義ファイルに移動します（それが存在していれば）。
    </p>
  </dd>
</dl>

<p>スニペットファイルが見つかると、バッファが後述する <code>snippet-mode</code> に設定され、スニペットの編集を始めることができます。
</p>

<h3 id="using-the-snippet-mode-major-mode">メジャーモード <code>snippet-mode</code> を使う</h3>

<p>スニペットを編集するためのメジャーモード <code>snippet-mode</code> があります。
<code>M-x snippet-mode</code> とすることで、バッファをこのモードに設定することができます。
このモードは、それなりに有用な構文ハイライトを提供してくれます。
</p>

<p>このモードでは、２個のコマンドが定義されています：
</p>

<dl>
  <dt>・<code>M-x yas/load-snippet-buffer</code></dt>
  <dd>
    <p>スニペットを編集しているとき、そのスニペットを現在のモードおよびメニューに読み込みます。
     このコマンドは <code>snippet-mode</code> ではデフォルトで <code>C-c C-c</code> にキーバインドされています。
    </p>
  </dd>
  <dt>・<code>M-x yas/tryout-snippet</code></dt>
  <dd>
    <p>スニペットを編集しているとき、新しい空のバッファを開き、そのバッファを適切なメジャーモードに設定し、スニペットをそこに挿入します。
    これにより、そのスニペットが実際にどんなふうに展開されるのかを確認することができます。
    このコマンドは <code>snippet-mode</code> では <code>C-c C-t</code> にキーバインドされています。
    </p>
  </dd>
</dl>

<p><em>スニペットを書くためのスニペット</em>もあります：
<code>vars</code> と
<code>$f</code> と
<code>$m</code> です :-)
</p>

<h2 id="file-content">ファイルの内容</h2>

<p>スニペットを定義しているファイルには、通常、展開されるテンプレートが書かれています。
</p>

<p>省略可能ですが、もしファイルに <code># --</code> という行が含まれていた場合、その行より上にある行はコメントとして扱われます。
それらの行の一部は<em>ディレクティブ</em>（あるいはメタデータ）になることもあります。
スニペットのディレクティブは <code># property: value</code> のような形式で、その後に書かれているスニペットの属性を微調整するものです。
もし、ファイルの中に <code># --</code> という行が含まれていない場合、ファイル全体がスニペットのテンプレートとみなされます。
</p>

<p>以下に典型的な例を示します：
</p>

<div class="highlight"><pre>#contributor : pluskid &lt;pluskid@gmail.com&gt;
#name : __...__
# --
__${init}__
</pre></div>

<p>現在サポートされているディレクティブを以下に示します：
</p>

<h3 id="key-snippet-abbrev"><code># key:</code> スニペット省略形</h3>

<p>これはおそらくもっとも重要なディレクティブです。
スニペットを展開するときに <code>yas/trigger-key</code> を押す前に入力する省略形です。
</p>

<p>このディレクティブを指定しない場合、スニペットが書かれていたファイルの名前がデフォルト値として使われます。
ただし、YASnippet がファイル名をトリガーとみなさないように設定されている場合は別です（<a href="./snippet-organization.html">Organizing snippets の章</a>の <a href="./snippet-organization.html#yas-ignore-filenames-as-triggers"><code>yas/ignore-filenames-as-triggers</code> のところ</a>を参照してください）。
もし YASnippet がファイル名をトリガーとみなさないように設定されていた場合は、snippet key の仕組みではそのスニペットを展開できないことになります。
</p>

<p>snippet key が ASCII 文字以外であったり、ファイル名として妥当なものでなかったり（たとえばスラッシュ <code>/</code> を含むとか）することがあります。
そういったスニペットでは、この <code>key</code> 属性を定義することで、snippet key としてファイル名がそのまま使われないようにしてください。
</p>

<h3 id="name-snippet-name"><code># name:</code> スニペット名</h3>

<p>これはスニペットの一行だけの説明書きです。
この説明書きはメニューに表示されます。
よく似たスニペットを区別するためにも、
そのスニペットをうまく説明する名前を付けるとよいでしょう。
</p>

<p>この名前を省略した場合、デフォルトでは、スニペットを読み込んだファイルの名前が使われます。
</p>

<h3 id="condition-snippet-condition"><code># condition:</code> スニペットの展開条件</h3>

<p>これは、一片の Emacs-lisp コードです。
スニペットが条件を持つ場合、その条件コードを評価して nil 以外の値になったときだけスニペットは展開されます。
</p>

<p><a href="./snippet-expansion.html">Expanding snippets の章</a>の <a href="./snippet-expansion.html#the-condition-system"><code>yas/buffer-local-condition</code> のところ</a>も参照してください。
</p>

<h3 id="group-snippet-menu-grouping"><code># group:</code> スニペットメニューのグルーピング</h3>

<p>メニューバーの項目からスニペットを展開しようとしたとき、ここで与えられたモードに対応するスニペットはサブメニューにグルーピングされます。
この機能は、あるモードに対するスニペットがあまりに多くて、メニューが長くなりすぎるようなときに便利です。
</p>

<p>この <code># group:</code> 属性は、メニューの構築にだけ影響します（<a href="./snippet-menu.html">the YASnippet menu の章</a>を参照）。
スニペットをサブディレクトリに分類して、特殊ファイル <code>.yas-make-groups</code> を使うと、このディレクティブと同じ効果が得られます（<a href="./snippet-organization.html">Organizing Snippets の章</a>を参照）。
</p>

<p>この <code># group:</code> ディレクティブの例としては、<code>ruby-mode</code> 向けに同梱されているスニペットを参照してください。
グループはネストすることも可能です。たとえば、<code>control structure.loops</code> という記述は、<code>control structure</code> グループの下にある <code>loops</code> グループの下にそのスニペットがあることを表します。
</p>

<h3 id="expand-env-expand-environment"><code># expand-env:</code> 展開する環境</h3>

<p>これは、<code>let <em>varlist form</em></code> の形をした一片の Emacs-lisp コードです。
すなわち、変数への値の割り当てのリストのリストです。
これは、スニペットが展開されるときの変数の値を上書きするために使うことができます。
</p>

<p>上書きする意味がある変数としては、<code>yas/wrap-around-region</code> と <code>yas/indent-line</code> があります（<a href="./snippet-expansion.html">Expanding Snippets の章</a>を参照）。
</p>

<p>例として、あなたは普段、<code>yas/indent-line</code> を <code>'auto</code> に、<code>yas/wrap-around-region</code> を <code>t</code> に設定しているとします。
残念ながら、この、とりわけ見事なアスキーアートは、それらの設定によって台無しになってしまうことでしょう。
こんなとき、次のように使うのです：
</p>

<div class="highlight"><pre># name : ASCII home
# expand-env: ((yas/indent-line &#39;fixed) (yas/wrap-around-region &#39;nil))
# --
                welcome to my
            X      humble
           / \      home,
          /   \      $0
         /     \
        /-------\
        |       |
        |  +-+  |
        |  | |  |
        +--+-+--+
</pre></div>

<h3 id="binding-direct-keybinding"><code># binding:</code> 直接的なキーバインド</h3>

<p>Emacs の通常のキーバインドでスニペットをダイレクトに展開するために、このディレクティブが使えます。
そのキーバインドは、そのスニペットが対象としているメジャーモードにちなんだ名前の Emacs keymap に登録されます。
</p>

<p>さらに、変数 <code>yas/prefix</code> は、普段あなたがコマンドにつけているプレフィックスに設定されます。
これを使うと、ひとつのスニペットにちょっとしたバリエーションをつけられます。
たとえば、次の &quot;html-mode&quot; スニペットのように：
</p>

<div class="highlight"><pre>#name : &lt;p&gt;...&lt;/p&gt;
#binding: &quot;C-c C-c C-m&quot;
# --
&lt;p&gt;`(when yas/prefix &quot;\n&quot;)`$0`(when yas/prefix &quot;\n&quot;)`&lt;/p&gt;
</pre></div>

<p>この割り当ては、keymap <code>html-mode-map</code> に記録されます。
p タグを改行付きで展開したいときには、&quot;C-u C-c C-c C-m&quot; と押すだけです。
&quot;C-u&quot; を省くと、改行なしで p タグが展開されます。
</p>

<p>メジャーモードの名前に基づく keymap の選択を上書きすることができます。
このディレクティブにコンスセルを指定してください。そのコンスセルの最初の要素を、キーバインドを記録させたい keymap の名前にします。
</p>

<div class="highlight"><pre>#name : &lt;p&gt;...&lt;/p&gt;
#binding: (rinari-minor-mode-map . &quot;C-c C-c C-m&quot;)
# --
&lt;p&gt;`(when yas/prefix &quot;\n&quot;)`$0`(when yas/prefix &quot;\n&quot;)`&lt;/p&gt;
</pre></div>

<p><strong>注：</strong>
この機能はまだ<strong>実験的な</strong>ものです。YASnippet の将来のリリースでは無くなったり変更されたりするかもしれません。
慎重にお使いください。
多くの基本的なモードで重要なキーバインドを上書きしてしまうのは容易で、元の定義に戻すのは困難です。
とりあえず、どのキーバインドが有効になっているかは、変数 <code>yas/active-keybindings</code> をみればわかります。
また、関数 <code>yas/kill-snippet-keybindings</code> は、すべてのキーバインドを取り消す（元に戻す）ことを試みてくれます。
</p>

<h3 id="contributor-snippet-author"><code># contributor:</code> スニペットの作者</h3>

<p>このディレクティブは付加的なもので、スニペットの機能にはなにも影響を与えませんが、見栄えがします。
</p>

<h2 id="template-syntax">テンプレートの構文</h2>

<p>スニペットのテンプレートの構文は、シンプルですが強力です。TextMate の構文にとてもよく似ています。
</p>

<h3 id="plain-text">プレインテキスト</h3>

<p>テンプレートの中身としては、任意のテキストが書けます。
テキストは、<code>$</code> および <code>`</code> を除き、プレインテキストと解釈されます。
これらの文字をエスケープするにはバックスラッシュ（円記号）が必要です (<code>\$</code> or <code>\`</code>)。
バックスラッシュ（円記号）それ自体のエスケープ、つまり <code>\\</code> が必要な場合もあります。
</p>

<h3 id="embedded-emacs-lisp-code">埋め込まれた Emacs-lisp コード</h3>

<p>バッククォート (<code>`</code>) で囲むことで、Emacs-Lisp のコードをテンプレート中に埋め込むことができます。
その lisp フォームはスニペットが展開されるときに評価されます。
その評価は、スニペットが展開されるバッファの中で（そのバッファの environment で）評価されます。
</p>

<p><code>c-mode</code> でヘッダファイルの二重読み込みガード文を動的に生成する、というサンプルを以下に示します：
</p>

<div class="highlight"><pre>#ifndef ${1:_`(upcase (file-name-nondirectory (file-name-sans-extension (buffer-file-name))))`_H_}
#define $1

$0

#endif /* $1 */
</pre></div>

<p>YASnippet のバージョン 0.6 以降では、スニペットの展開は、ある特別な Emacs-lisp 変数の束縛のもとで行われます。
そのひとつは <code>yas/selected-text</code> です。
以下のようにスニペットを定義することができます：
</p>

<div class="highlight"><pre>for ($1;$2;$3) {
  `yas/selected-text`$0
}
</pre></div>

<p>このように定義すると、スニペットの中に選択領域を「包み込む」ことができます。
さらに言えば、変数 <code>yas/wrap-around-region</code> を <code>t</code> に設定することで、この動作を自動的に行うようにすることもできます。
</p>

<h3 id="tab-stop-fields">タブストップ</h3>

<p>タブストップというのは、<code>TAB</code> と <code>S-TAB</code> で行ったり来たりできるフィールドです。
タブストップは、記号 <code>$</code> とそれに続く数字１個で記述します。
<code>$0</code> は特別な意味を持っていて、スニペットの <em>exit point</em> を表します。
これは、すべてのフィールドを一巡したときに最後にたどりつく場所です。
典型的な例は以下の通りです：
</p>

<div class="highlight"><pre>&lt;div$1&gt;
    $0
&lt;/div&gt;
</pre></div>

<h3 id="placeholder-fields">プレースホルダー</h3>

<p>タブストップは、デフォルト値をとることができます。それはプレースホルダーと呼ばれています。その文法は以下のようになります：
</p>

<div class="highlight"><pre>${N:default value}
</pre></div>

<p>これらはタブストップに対するデフォルト値となります。
ユーザがそのタブストップで初めて文字をタイプした時点で、そのデフォルト値はユーザのタイプした文字で置き換えられます。
そのフィールドに対して「<a href="#mirrors">ミラー</a>」や「変換」を指定したいのでなければ、
数字の指定を省略することができます。
</p>

<h3 id="id2">ミラー</h3>

<p>プレースホルダーのついたタブストップは、ひとつの<em>フィールド</em>とみなすことができます。
ひとつのフィールドは１個または複数の「ミラー」を持つことができます。
ユーザがフィールドのテキストを書き換えると、そのフィールドのミラーが更新されます。
以下に例を示します：
</p>

<div class="highlight"><pre>\begin{${1:enumerate}}
    $0
\end{$1}
</pre></div>

<p>ユーザが <code>${1:enumerate}</code> フィールドに &quot;<code>document</code>&quot; とタイプすると、
その &quot;<code>document</code>&quot; という単語が <code>\end{$1}</code> にも挿入されます。
良い解説動画があります： <a href="http://www.youtube.com/watch?v=vOj7btx3ATg">YouTube</a> or <a href="http://yasnippet.googlecode.com/files/yasnippet.avi"> avi video</a>
</p>

<p>同じ番号を付けられたタブストップは、ミラーとして機能します。
同じ番号を付けられたどのタブストップもデフォルト値を持っていない場合、スニペットファイル中で一番上に書かれているタブストップがフィールドとして選ばれ、それ以外はミラーとなります。
</p>

<h3 id="mirrors-with-transformations">変換を伴うミラー</h3>

<p>もし、プレースホルダー <code>${n:</code> のデフォルト値が <code>$(</code> で始まる場合、
それはフィールド <code>n</code> に対する「変換を伴うミラー」と解釈されます。
ミラーのテキストは、「変換」にしたがって求められたものとなります。
この「変換」は Emacs-lisp コードであり、このコードは、変数 <code>text</code> （もしくは <code>yas/text</code>）がフィールド <code>n</code> の中身に束縛されている環境で評価されます。
以下に Objective-C 向けのサンプルを示します：
</p>

<div class="highlight"><pre>- (${1:id})${2:foo}
{
    return $2;
}

- (void)set${2:$(capitalize text)}:($1)aValue
{
    [$2 autorelease];
    $2 = [aValue retain];
}
$0
</pre></div>

<p><code>${2:$(capitalize text)}</code> を見てみてください。
これは、フィールドではなく「変換を伴うミラー」です。
実際のフィールドは最初の行の <code>${2:foo}</code> です。
ユーザが <code>${2:foo}</code> にテキストを入力すると、
「変換」が評価され、
変換後のテキストとしてミラーに書かれます。
つまり、上記のサンプルでは、ユーザがフィールドに &quot;<code>baz</code>&quot; とタイプすると、変換後のテキストは &quot;<code>Baz</code>&quot; となります。
この例も上記の動画で見られます。
</p>

<p>もうひとつ、<code>rst-mode</code> 向けのサンプルを示します。
reStructuredText では、上下を &quot;<code>===</code>&quot; で囲ったテキストがドキュメントのタイトルになります。
この &quot;<code>===</code>&quot; は、少なくともテキストと同じ長さでなければなりません。
つまり、
</p>

<div class="highlight"><pre>=====
Title
=====
</pre></div>

<p>は正しいタイトルですが、</p>

<div class="highlight"><pre>===
Title
===
</pre></div>

<p>は正しくありません。
rst のタイトル部のためのスニペットは、以下のようになります：
</p>

<div class="highlight"><pre>${1:$(make-string (string-width text) ?\=)}
${1:Title}
${1:$(make-string (string-width text) ?\=)}

$0
</pre></div>

<h3 id="fields-with-transformations">変換を伴うフィールド</h3>

<p>YASnippet のバージョン 0.6 以降では、フィールドの内部で lisp による変換を行うことができます。
この機能は「変換を伴うミラー」とほとんど同じように動きますが、その lisp コードの評価（値の変換）は次のタイミングで行われます。
すなわち、ユーザがそのフィールドに入ったとき、そのフィールドに変更を加えた時、そのフィールドから抜けるとき、このいずれのタイミングでも評価が行われます。
</p>

<p>この機能の構文は、「変換を伴うミラー」とはわずかに違います。その違いは、パーサがフィールドとミラーを区別するためのものです。
次の例において：
</p>

<div class="highlight"><pre>#define &quot;${1:mydefine$(upcase yas/text)}&quot;
</pre></div>

<p>ユーザがこのフィールドに入ると、&quot;<code>mydefine</code>&quot; は自動的に &quot;<code>MYDEFINE</code>&quot; に変換されます。
ユーザがテキストを入力するたびに、この変換は行われます。
</p>

<p>ひとつ注意してください。
この「変換を伴うフィールド」を「変換を伴うミラー」と区別するために、YASnippet はコロン (<code>:</code>) とドルマーク (<code>$</code>) の間に追加のテキストを必要とします（訳注：上記の例での &quot;<code>mydefine</code>&quot; のようにプレースホルダーを書いておく必要があります）。
もし、この追加のテキストを書きたくない場合、２個の <code>$</code> を使ってください。
</p>

<div class="highlight"><pre>#define &quot;${1:$$(upcase yas/text)}&quot;
</pre></div>

<p>次のことにも注意してください。
変換が行われるとき、それと同時に、フィールドの値が変更され、内部的な「更新状態」が <code>true</code> に設定されます。
結果として、通常のフィールドに対して行われる「自動的な削除」は行われません。
この挙動は意図的なものです。
</p>

<h3 id="choosing-fields-value-from-a-list-and-other-tricks">リストからのフィールドの値の選択、および他の技</h3>

<p>これまで見てきたように、フィールドの値の変換は、ユーザがそのフィールドに入った後に行われ、またいくつかの便利な変数束縛（特に <code>yas/field-modified-p</code> と <code>yas/moving-away-p</code>）の元で評価されます。
この特長を利用すると、あるフィールドに対して、そのデフォルト値を選択できるようにすることができます。
</p>

<p><code>yas/choose-value</code> はこの機能を提供します。
例：
</p>

<div class="highlight"><pre>&lt;div align=&quot;${2:$$(yas/choose-value &#39;(&quot;right&quot; &quot;center&quot; &quot;left&quot;))}&quot;&gt;
  $0
&lt;/div&gt;
</pre></div>

<p>さきに挙げた２個の変数をどのように使って書かれているか、関数 <code>yas/choose-value</code> そのものの定義を見てみてください。
</p>

<p>別の使い方を以下に示します。これは LaTeX-mode 向けのスニペットで、ユーザがフィールド 2 に移動したときに <code>reftex-label</code> を呼ぶ、というものです。
この例では <code>yas/modified-p</code> を直接使っています。
</p>

<div class="highlight"><pre>\section{${1:&quot;Titel der Tour&quot;}}%
\index{$1}%
\label{{2:&quot;waiting for reftex-label call...&quot;$(unless yas/modified-p (reftex-label nil &#39;dont-
insert))}}%
</pre></div>

<p>関数 <code>yas/verify-value</code> の定義では、もうひとつ別の巧みな技を使っていて、<code>yas/moving-away-p</code> を活用しています。
ぜひ実際に試してみてください。
<a href="http://groups.google.com/group/smart-snippet/browse_thread/thread/282a90a118e1b662">こちらのスレッド</a>もチェックしてみてください。
</p>

<h3 id="nested-placeholder-fields">入れ子になったプレースホルダー</h3>

<p>YASnippet のバージョン 0.6 以降では、入れ子になったプレースホルダーを使うことができます：
</p>

<div class="highlight"><pre>&lt;div${1: id=&quot;${2:some_id}&quot;}&gt;$0&lt;/div&gt;
</pre></div>

<p>この記述は、<code>div</code> 要素に <code>id</code> 属性を指定するかどうか、ユーザが選択できるようにしてくれます。
id 要素を展開した後に TAB を押すと、&quot;<code>some_id</code>&quot; を好きなものに書き換えられます。
あるいは、単に <code>C-d</code> を押せば（これは <code>yas/skip-and-clear-or-delete-char</code> を実行するキーバインドです）、
すぐに exit marker に進みます（訳注：タブストップ <code>$0</code> に移動します）。
</p>

<p>ちなみに、<code>C-d</code> は、カーソルがフィールドの先頭にあって、<em>かつ</em>、フィールドの値がまだ変更されていなかった場合に限り、そのフィールドをクリアします。
そうでなければ、<code>C-d</code> は通常の Emacs の機能である <code>delete-char</code> コマンドを実行します。
</p>

<h2 id="customizable-variables">カスタム可能な変数</h2>

<h3 id="yas-trigger-key"><code>yas/trigger-key</code></h3>

<p>この変数で指定されたキーは、関数 <code>yas/minor-mode</code> が有効な時に <code>yas/expand</code> に割り当てられます。
</p>

<p>この変数の値は文字列で、<code>read-kdb-macro</code> によって Emacs 内部のキー表現に変換されるものです。
</p>

<p>デフォルトの値は <code>&quot;TAB&quot;</code> です。
</p>

<h3 id="yas-next-field-key"><code>yas/next-field-key</code></h3>

<p>この変数で指定されたキーは、スニペットがアクティブなときに次のフィールドに移動する操作になります。
</p>

<p>この変数の値は文字列で、<code>read-kdb-macro</code> によって Emacs 内部のキー表現に変換されるものです。
</p>

<p>キーのリストを与えることもできます。
</p>

<p>デフォルトの値は <code>&quot;TAB&quot;</code> です。
</p>

<h3 id="yas-prev-field-key"><code>yas/prev-field-key</code></h3>

<p>この変数で指定されたキーは、スニペットがアクティブな時にひとつ前のフィールドに移動する操作になります。
</p>

<p>この変数の値は文字列で、<code>read-kdb-macro</code> によって Emacs 内部のキー表現に変換されるものです。
</p>

<p>キーのリストを与えることもできます。
</p>

<p>デフォルトの値は <code>(&quot;&lt;backtab&gt;&quot; &quot;S-tab&quot;)</code> です。
</p>

<h3 id="yas-skip-and-clear-key"><code>yas/skip-and-clear-key</code></h3>

<p>この変数で指定されたキーは、現在アクティブなフィールドをクリアする操作になります。
</p>

<p>この変数の値は文字列で、<code>read-kdb-macro</code> によって Emacs 内部のキー表現に変換されるものです。
</p>

<p>キーのリストを与えることもできます。
</p>

<p>デフォルトの値は <code>&quot;C-d&quot;</code> です。
</p>

<h3 id="yas-good-grace"><code>yas/good-grace</code></h3>

<p>もし nil でない場合、スニペット定義の中にインラインで書かれた Emacs-lisp の評価の途中でエラーを上げません（例外を投げません）。
その代わりに文字列 <code>"[yas] error"</code> を返します。
</p>

<h3 id="yas-indent-line"><code>yas/indent-line</code></h3>

<p>変数 <code>yas/indent-line</code> は、インデントを制御します。
デフォルトでは <code>'auto</code> に束縛されていて、スニペットが挿入されるときに、その挿入先のバッファのモードにしたがってスニペットがインデントされるようになっています。
</p>

<p>もうひとつの変数 <code>yas/also-auto-indent-first-line</code> は、nil でないときに、まさに変数名どおりの仕事をします（訳注：スニペットの１行目も自動的にインデントされます。この変数が nil のときは、スニペットの１行目はインデントされません）。
:-)
</p>

<p>スニペットのテンプレートで「ハードコーディングされたインデント」を使いたいときは、この変数 <code>yas/indent-line</code> を <code>fixed</code> に設定します。
</p>

<p>スニペットごとにインデント制御を変えたいときは、<a href="#expand-env-expand-environment">ディレクティブ <code># expand-env:</code> の節</a>を参照してください。
</p>

<p>YASnippet のもっと前のバージョンとの後方互換性のため、スニペットの中に <code>$&gt;</code> と書くと、その行が <code>(indent-according-to-mode)</code> によってインデントされます。
この挙動は、<code>yas/indent-line</code> が <code>'auto</code> 以外の値に設定されているときだけ有効になります。
</p>

<div class="highlight"><pre>for (${int i = 0}; ${i &lt; 10}; ${++i})
{$&gt;
$0$&gt;
}$&gt;
</pre></div>

<h3 id="yas-wrap-around-region"><code>yas/wrap-around-region</code></h3>

<p>もし nil でない値だった場合、YASnippet はスニペットの exit marker （タブストップ <code>$0</code>）の位置に現在の選択領域（のテキスト）を挿入します。
もしこの変数が <code>t</code> に設定されていた場合、<code>$0</code> の位置に <code>`yas/selected-text`</code> とインラインで書いたのと同じ結果になります。
</p>

<p>ほとんどの Emacs システムでは、文字入力を開始することで選択領域が削除されます。
そのため、この機能はたいてい <code>yas/insert-snippet</code> コマンドでスニペットを選択する場合に使われます。
</p>

<p>また一方で、この変数の値が <code>cua</code> だった場合、YASnippet は、文字入力を開始することによって削除された選択領域のうちで最新のものを探して適用します。
この機能を使うと次のようなことが可能になります。まず領域を選択し、snippet key を入力し（この時点で選択領域は削除されます）、それから <code>yas/trigger-key</code> を押す、という操作によって、削除されてしまった選択領域をスニペットの中に復活させることが可能になります。
</p>

<h3 id="yas-triggers-in-field"><code>yas/triggers-in-field</code></h3>

<p>もし nil でない値だった場合、<code>yas/next-field-key</code> は「積み重なった」展開のトリガーとなります。
「積み重なった」展開というのは、あるスニペットの展開が別のスニペットの展開を含むことを指します。
この変数 <code>yas/triggers-in-field</code> の値が nil だった場合は、<code>yas/next-field-key</code> は単に次のフィールドに移動するだけになります。
</p>

<h3 id="yas-snippet-revival"><code>yas/snippet-revival</code></h3>

<p>nil でない値だった場合、undo/redo のあとにスニペットのフィールドが再びアクティブになります。
</p>

<h3 id="yas-after-exit-snippet-hook-and-yas-before-expand-snippet-hook"><code>yas/after-exit-snippet-hook</code> および <code>yas/before-expand-snippet-hook</code></h3>

<p>これらのフックは、それぞれ、スニペットから抜けた後と、スニペットを挿入する前に、呼ばれます。
もし、これらのフックの奇妙で有効な使い道を見つけたら、それはおそらく YASnippet の設計上のミスなので、私たちに知らせてください。
</p>

<h2 id="importing-textmate-snippets">TextMate スニペットの移植</h2>

<p>TextMate の &quot;<code>.tmSnippet</code>&quot; XML ファイルを取り込んで YASnippet の定義を生成するためのツールが２個あります：
</p>

<ul>
  <li><a href="http://code.nokrev.com/?p=snippet-copier.git;a=blob_plain;f=snippet_copier.py">Jeff Wheeler 氏による Python スクリプト</a></li>
  <li><a href="http://www.neutronflux.net/2009/07/28/shoulda-snippets-for-emacs/">Rob Christie 氏</a>による Ruby ツール <a href="http://yasnippet.googlecode.com/svn/trunk/extras/textmate_import.rb"><code>textmate_import.rb</code></a> （この SVN repository にアップロードされています）</li>
</ul>

<p>この章では、<em>２番目の</em>ものについて手短にとりあげます。
</p>

<p><code>textmate_import.rb</code> と、あなたの使いたい TextMate バンドルを、ダウンロードしてください。
</p>

<div class="highlight"><pre>$ curl -O http://yasnippet.googlecode.com/svn/trunk/extras/textmate_import.rb
$ svn export http://svn.textmate.org/trunk/Bundles/HTML.tmbundle/
</pre></div>

<p>次に、以下のように <code>textmate_import.rb</code> を実行します：
</p>

<div class="highlight"><pre>$ ./textmate_import.rb -d HTML.tmbundle/Snippets/ -o html-mode -g HTML.tmbundle/info.plist
</pre></div>

<p>最終的に、<code>html-mode</code> サブディレクトリが得られ、その中には TextMate から移植されたスニペットが置かれているハズです。
</p>

<div class="highlight"><pre>$ tree html-mode # to view dir contents, if you have &#39;tree&#39; installed
</pre></div>

<p>オプション <code>-g</code> は省略可能ですが、このツールがスニペットのグルーピングを把握する手助けになります。
<a href="./snippet-organization.html">Organizing Snippets の章</a>にしたがって <code>html-mode</code> ディレクトリの中に <code>.yas-make-groups</code> と <code>.yas-ignore-filename-triggers</code> を置くのを忘れないようにしてください。
</p>

<p>指定可能な引数の一覧を見るには、<code>textmate_import.rb --help</code> と実行してみてください。
</p>

<p>スニペットの移植はまだ完ぺきではないことに留意してください。
いくつかの（あるいは、たくさんの）スニペットで修正が必要かもしれません。
それらの修正をしたなら、google group に投稿してください。
もっと言うと、その修正を自動化できるように <code>textmate_import.rb</code> にパッチを当てて、そのパッチを投稿してください。
</p>

</div><!-- class="contents" -->

</body></html>
